﻿--[[
牧师：Priest 
盗贼：Rogue 
德鲁伊：Druid 
猎人：Hunter 
圣骑士：Paladin 
法师：Mage 
撒满：Shaman 
术士：Warlock 
战士：Worrior 
]]--

local SHARDS_NEED=5
local targetType="",""
local p = JMacro.player


local function JMakeSimpleSequence(spells)
	if(not spells)then return '' end
	local start, duration, enable ,cooldown,jspell
	local sequence = {}
	local text=''
	--初始化 spell信息
	for i = 1 , #spells do 
		if(JMacroSpells[spells[i]])then
			sequence[#sequence+1]= spells[i]
		end
	end
	for i = 1 , #sequence do
		if(i~=1)then 
			text = text ..','			
		end
		text = text ..sequence[i]
	end
	return text
end

local function  JMakeSequenceMacro(spells,condition)
	local start, duration, enable ,cooldown,jspell
	local text = ''
	local sequence = {}
	local jspells = {}
	--初始化 spell信息
	for i = 1 , #spells do 
		jspell = JMacroSpells[spells[i]]
		if(jspell)then
			jspell.tempStart ,jspell.tempDuration , jspell.tempEnable = GetSpellCooldown(s)
			jspell.eff.cooldown = jspell.eff.cooldown or 1
			if(jspell.tempDuration) then
				jspell.tempNextTime = jspell.tempDuration
			else
				jspell.tempNextTime = 0
			end
			jspells[#jspells+1] = jspell
		end
	end
	table.sort(jspells,function(a,b) return a.tempNextTime < b.tempNextTime or(a.tempNextTime==b.tempNextTime and a.eff.cooldown>b.eff.cooldown) end)
	local sec = 0
	while(sec<120 and #sequence<10)do
		sec  = jspells[1].tempNextTime
		sequence[#sequence+1]=jspells[1].name
		jspells[1].tempNextTime = sec+jspells[1].eff.cooldown
		table.sort(jspells,function(a,b) return a.tempNextTime < b.tempNextTime or(a.tempNextTime==b.tempNextTime and a.eff.cooldown>b.eff.cooldown) end)
	end
	
	for i = 1 , sequence do
		if(i~=1)then 
			text = text ..','			
		end
		text = text ..sequence[i]
	end
end

local function JMakeSpellMacro(spells,condition)
	if(spells==nil)then return "" end
	local text = "";
	local prefix = "[";
	if(condition~=nil)then
		prefix = prefix .. condition .. ","
	end
	local ss = {}
	for i=1,#spells do
		if(spells[i]==nil)then break end
		if(GetSpellLink(spells[i]))then
			ss[#ss+1] = spells[i]
		end
	end
	for i=#ss,1,-1 do

		if(i==1 and condition~=nil)then
			text = text.."["..condition.."]";
		elseif(i==2)then 
			text=text..prefix.."mod:alt]"
		elseif(i==3)then 
			text=text..prefix.."mod:shift]"
		elseif(i==4)then 
			text=text..prefix.."mod:ctrl]"
		elseif(i==5)then 
			text=text..prefix.."mod:alt/shift]"
		end
		text = text .. spells[i]..";"
	end
	return text;
end

function JMacroWarlockHanlder(macroname)

	local combatspell,prefix
	local lastTargetType = targetType
	targetType = UnitCreatureType("target")

	if(p.class=="WARLOCK")then
		--是否有治疗石,是否有复活石,是否有魔甲术,是否绑定灵魂,是否有宠物
		--if(UnitHasMana("target") and UnitManaPercent("player") < 0.8)then
		--	combatspell="[combat,mod:alt]吸取生命;[combat,mod:shift]吸取灵魂;[combat]吸取法力;"
		--elseif(UnitHealthPercent("player") < 0.75)then
		--	combatspell="[combat,mod:alt]吸取法力;[combat,mod:shift]吸取灵魂;[combat]吸取生命;"
		--else
			combatspell="[combat,mod:alt]吸取法力;[combat,mod:shift]吸取生命;[combat]吸取灵魂;"
		--end
		prefix = "#showtooltip\n/use "..combatspell
		if(UnitHealthPercent("player")<0.4)then 
			return JMacroFoodHandler(macroname,prefix)
		elseif(GetSpellLink("生命之血") and UnitHealthPercent("player")<0.75 and GetSpellCooldown("生命之血")==0)then
			return JMacroEdit(macroname,prefix.."生命之血")
		elseif(HasPet() and GetSpellLink("生命通道") and UnitHealthPercent("player")>0.75 and UnitHealthPercent("pet")<0.6)then
			return JMacroEdit(macroname,prefix.."生命通道")
		elseif(HasPet() and UnitHealthPercent("pet")<0.5)then
			return JMacroBandageHandler(macroname,prefix)
		end
		if(UnitManaPercent("player")<0.25)then
			if(GetSpellLink("黑暗契约") and UnitManaPercent("pet")>0.35)then
				return JMacroEdit(macroname,prefix.."黑暗契约")
			elseif(GetSpellLink("生命分流") and UnitHealthPercent("player")>0.65)then
				return JMacroEdit(macroname,prefix.."生命分流")
			else
				return JMacroFoodHandler(macroname,prefix)
			end
		end	
		if(IsSwimming() and GetSpellLink("魔息术"))then
			if(UnitIsPlayer("target") and UnitIsFriend("target", "player") and  not HasBuff("target","魔息术")) then 
				return JMacroEdit(macroname,prefix.."[help,nodead][target=player]魔息术")
			elseif(not HasBuff("player","魔息术"))then 
				return JMacroEdit(macroname,prefix.."[target=player]魔息术")
			end
		end
		
		if(not HasBuff("player","魔甲术") and not HasBuff("player","恶魔皮肤") and not HasBuff("player","邪甲术") ) then
			 local ss={}
			if(GetSpellLink("邪甲术"))then
				ss[#ss+1]="邪甲术"
			end 
			if(GetSpellLink("魔甲术"))then
				ss[#ss+1]="魔甲术"
			elseif(GetSpellLink("恶魔皮肤"))then
				ss[#ss+1]="恶魔皮肤"
			end 
			if(#ss > 0)then 
				local text = prefix
				for i=#ss,1,-1 do
					if(i==2)then 
						text=text.."[mod:alt]"
					elseif(i==3)then 
						text=text.."[mod:shift]"
					elseif(i==4)then 
						text=text.."[mod:ctrl]"
					elseif(i==5)then 
						text=text.."[mod:alt/shift]"
					end
					text = text .. ss[i]..";"
				end
				return JMacroEdit(macroname,text)
			end 
		end
		
		if(UnitExists("pet") and (not UnitIsDead("pet")) and GetSpellLink("灵魂链接") and (not HasBuff("player","灵魂链接")))then
			return JMacroEdit(macroname,prefix.."灵魂链接")
		end
		
		local hasMainHandEnchant, mainHandExpiration, mainHandCharges, hasOffHandEnchant, offHandExpiration, offHandCharges = GetWeaponEnchantInfo()
		if(not hasMainHandEnchant)then
			local ss={}
			local firestone = GetExistingItem({"极效火焰石","特效火焰石","强效火焰石","火焰石","次级火焰石","初级火焰石"})
			local spellstone = GetExistingItem({"极效法术石","特效法术石","强效法术石","法术石","次级法术石","初级法术石"})
			if(firestone~=nil)then
				ss[#ss+1]=firestone
			end 
			if(spellstone~=nil)then
				ss[#ss+1]=spellstone
			end
			if(#ss>0)then
				return JMacroEdit(macroname,prefix..JMakeSpellMacro(ss).."\n/cast 16")
			elseif(HasItem("灵魂碎片"))then
				--local ss={}
				if(GetSpellLink("制造火焰石"))then
					ss[#ss+1]="制造火焰石"
				end 
				if(GetSpellLink("制造法术石"))then
					ss[#ss+1]="制造法术石"
				end
				if(#ss>0)then
					return JMacroEdit(macroname,prefix..JMakeSpellMacro(ss))
				end
			end
		end
		
		if(not UnitInBattleground("player"))then
		
			if(not IsMountedAny() and UnitManaPercent("player")>0.35 and not HasPet())then
			--[[
				if(GetSpellLink("恶魔支配") and GetSpellCooldown("恶魔支配")==0)then
					return JMacroEdit(macroname,"#showtooltip\n/cast 恶魔支配")
				end
			]]--
				if(HasItem("灵魂碎片"))then
					local ss={}
					if(GetSpellLink("召唤恶魔卫士"))then
						ss[#ss+1]="召唤恶魔卫士"
					end 
					if(GetSpellLink("召唤虚空行者"))then
						ss[#ss+1]="召唤虚空行者"
					end 
					if(GetSpellLink("召唤地狱猎犬"))then
						ss[#ss+1]="召唤地狱猎犬"
					end 
					if(GetSpellLink("召唤魅魔"))then
						ss[#ss+1]="召唤魅魔"
					end 
					if(GetSpellLink("召唤小鬼"))then
						ss[#ss+1]="召唤小鬼"
					end 
					if(#ss > 0)then 
						--local text = "#showtooltip\n/cast [combat,mod:alt]吸取法力;[combat,mod:shift]吸取生命;[combat]吸取灵魂;"
						local text=prefix
						--text = text .. "\n/stopmacro [target=pet,nodead]\n/cast "
						text = text.."\n/cast "
						for i=#ss,1,-1 do
							if(i==2)then 
								text=text.."[mod:alt]"
							elseif(i==3)then 
								text=text.."[mod:shift]"
							elseif(i==4)then 
								text=text.."[mod:ctrl]"
							elseif(i==5)then 
								text=text.."[mod:alt/shift]"
							end
							text = text .. ss[i]..";"
						end
						return JMacroEdit(macroname,text)
					end 
				elseif(GetSpellLink("召唤小鬼"))then 
					--return JMacroEdit(macroname,"#showtooltip\n/cast 召唤小鬼")
					return JMacroEdit(macroname,prefix.."\n/cast 召唤小鬼")
				end
			end
			if(GetSpellLink("制造灵魂石"))then
				local start1,duration1,enable1 = GetItemCooldown("初级灵魂石")
				local start2,duration2,enable2 = GetItemCooldown("次级灵魂石")
				local start3,duration3,enable3 = GetItemCooldown("灵魂石")
				local start4,duration4,enable4 = GetItemCooldown("强效灵魂石")
				local start5,duration5,enable5 = GetItemCooldown("特效灵魂石")
				local start6,duration6,enable6 = GetItemCooldown("极效灵魂石")
				--print(" d1"..duration1.." d2"..duration2.." d3"..duration3.." max"..math.max(duration1,duration2,duration3))
				if(math.max(duration1,duration2,duration3,duration4,duration5,duration6)<5 and ((UnitIsPlayer("target") and not HasBuff("target","灵魂石复活")) or not HasBuff("player","灵魂石复活")) )then
					local tarStr = ""
					if(UnitIsPlayer("target") and not HasBuff("target","灵魂石复活"))then tarStr="[help,nodead]" end
					if(HasItem("初级灵魂石"))then
						return JMacroEdit(macroname,prefix..tarStr.."[target=player] 初级灵魂石")
					elseif(HasItem("次级灵魂石"))then
						return JMacroEdit(macroname,prefix..tarStr.."[target=player] 次级灵魂石")
					elseif(HasItem("灵魂石"))then
						return JMacroEdit(macroname,prefix..tarStr.."[target=player] 灵魂石")
					elseif(HasItem("强效灵魂石"))then
						return JMacroEdit(macroname,prefix..tarStr.."[target=player] 强效灵魂石")
					elseif(HasItem("特效灵魂石"))then
						return JMacroEdit(macroname,prefix..tarStr.."[target=player] 特效灵魂石")
					elseif(HasItem("极效灵魂石"))then
						return JMacroEdit(macroname,prefix..tarStr.."[target=player] 极效灵魂石")
					elseif(HasItem("灵魂碎片"))then
						return JMacroEdit(macroname,prefix.."制造灵魂石")
					end
				end
			end
		end
		
		if(GetSpellLink("制造治疗石") and not HasItem("初级治疗石") and not HasItem("次级治疗石") and not HasItem("治疗石") and not HasItem("强效治疗石") and not HasItem("特效治疗石") and not HasItem("极效治疗石") and HasItem("灵魂碎片") )then
			if(GetSpellLink("灵魂仪式") and UnitInBattleground("player") or GetPartyMember(2)~=nil)then
				return JMacroEdit(macroname,prefix..JMakeSpellMacro({"灵魂仪式","制造治疗石"}))
			else
				return JMacroEdit(macroname,prefix.."制造治疗石")
			end
		end
		
		if(GetSpellLink("侦测隐形"))then
			if(UnitIsPlayer("target") and UnitIsFriend("target", "player") and  not HasBuff("target","侦测隐形")) then 
					return JMacroEdit(macroname,prefix.."[help,nodead][target=player]侦测隐形")
			elseif(not HasBuff("player","侦测隐形")) then
				return JMacroEdit(macroname,prefix.."[target=player]侦测隐形")
			end
		end
		if(GetSpellLink("吞噬暗影") and UnitChannelInfo("pet")~="吞噬暗影" and UnitManaPercent("pet")>0.1 and UnitHealthPercent("pet")<0.6)then
			return JMacroEdit(macroname,prefix.."吞噬暗影")
		elseif(GetSpellLink("黑暗契约") and UnitManaPercent("pet")>0.6 and UnitManaPercent("player")<0.7)then
			return JMacroEdit(macroname,prefix.."黑暗契约")
		elseif(GetSpellLink("生命分流") and UnitHealthPercent("player")>0.85 and UnitManaPercent("player")<0.5)then
			return JMacroEdit(macroname,prefix.."生命分流")
		elseif(lastTargetType=="人型生物" and GetSpellLink("食尸") and GetSpellCooldown("食尸")==0 and UnitHealthPercent("player")<0.65)then
			return JMacroEdit(macroname,prefix.."食尸")
		elseif(UnitHealthPercent("player")<0.4 or UnitManaPercent("player")<0.4)then 
			return JMacroFoodHandler(macroname,prefix)
		elseif(--not IsMountedAny() and 
			not IsSwimming() and IsOutdoors())then
				return JMacroEdit(macroname,prefix..JMakeSpellMacro(GetBestMountNames(false)))
				--[[
				local mountId = GetBestMountId(false)
				if(mountId~=nil)then
					local mountName = GetMountNameWithID(mountId)
					return JMacroEdit(macroname,prefix..mountName)
				end
				]]--
		end
			--return JMacroEdit(macroname,prefix.."\n/y [nocombat] JMacro 真牛叉!!\n/lol")
		return JMacroEdit(macroname,prefix.."\n/lol\n/script if(not InCombatLockdown())then SendChatMessage(\"JMacro 真牛叉!!\",\"YELL\") end")
		
	end
end

--[[
{
{condition,spell1,spell2}
{condition,spell1,spell2}
}

buff, spells are buffs

]]--
function JMacroConditionHandler(macroname,list,targetType,buff,prefix,condition,target)
	local spellset,spell,buffname,hasBuff,readySpells
	target=target or "target"
	if(not list)then return false end
	for i=1,#list do
		spellset = list[i]
		if(spellset[1]==nil or spellset[1](target,targetType))then  
		-- check spellset
			hasBuff=false
			if(buff)then
				for j=2,#spellset do
					spell = spellset[j]
					buffname = spell
					--TODO: 处理buffname与spellname不一样的情况
					if(HasBuff(target,buffname))then
						--JMacroDebug('has'..buffname)
						hasBuff = true
						break
					end
					--JMacroDebug('no'..buffname)
				end
			end
			if(not hasBuff)then 
				readySpells = {}
				for j=2,#spellset do
					spell = spellset[j]
					local start, duration, enable = GetSpellCooldown(spell)
					--JMacroDebug(spell..target)
					--JMacroDebug(IsSpellInRange(spell, target))
					if(GetSpellLink(spell) and enable and IsUsableSpell(spell)--and (spell[3]==nil or spell[3](targetType)) 
						and (not SpellHasRange(spell) or IsSpellInRange(spell, target)==1))then
						readySpells[#readySpells+1]=spell
					end
				end
				if(#readySpells>0)then
					--return JMacroEdit(macroname,prefix.."\n/cast "..JMakeSpellMacro(readySpells,'nocombat'))
					return JMacroEdit(macroname,prefix..JMakeSpellMacro(readySpells,condition))
				end
			end
		end
	end
	return false
end

function JMacroClassesHanlder(macroname)
	if(p.class == "WARLOCK")then return JMacroWarlockHanlder(macroname) end
	local conf=JMacroConfig[p.class] or {}
	local lastTargetType = targetType
	targetType = UnitCreatureType("target")
	--[[
	if(UnitExists("target"))then
	local class, classFileName = UnitClassBase("target")
	JMacroDebug(class)
	JMacroDebug(classFileName)
	JMacroDebug(targetType)
	end
	]]--
	local sequence = JMakeSimpleSequence(conf["sequence"])
	--JMacroDebug(sequence)
	local prefix="#showtooltip\n"
	if(UnitExists('pet'))then
		prefix=prefix.."\n/petattack [harm]"
	end
	local prefnoharm=prefix
	local prefno=prefix
	if(sequence and sequence~='')then 
		prefno=prefix.."/castsequence reset=target "..sequence 
		prefnoharm=prefix.."/castsequence [combat] reset=target "..sequence 
		prefix=prefix.."/castsequence [combat][harm] reset=target "..sequence 
	end
	local flag=false
	
	--友方buff放在自己身上
	flag = flag or JMacroConditionHandler(macroname,conf["help"],targetType,true,prefnoharm.."\n/cast ","nocombat,target=player","player") 
	
	local powerType, powerToken, altR, altG, altB = UnitPowerType("player")
	
	--Food and heal
	if(UnitHealthPercent("player")<conf["eat"][1] or (powerType==0 and UnitManaPercent("player")<conf["eat"][2]))then
		flag= flag or JMacroFoodHandler(macroname,prefnoharm)
	end
	--player 的 buff
	flag = flag or JMacroConditionHandler(macroname,conf["buff"],targetType,true,prefnoharm.."\n/cast ","nocombat","player") 
	--检查状态
	flag = flag or JMacroConditionHandler(macroname,conf["check"],targetType,false,prefnoharm.."\n/cast ","nocombat","player")
	--友方目标
	if(targetType~="非战斗宠物" and UnitIsFriend("target","player") )then
		if(UnitIsDead("target") )then
			flag = flag or JMacroConditionHandler(macroname,conf["dead"],targetType,true,prefnoharm.."\n/cast ","nocombat","target") 
		else
			flag = flag or JMacroConditionHandler(macroname,conf["help"],targetType,true,prefnoharm.."\n/cast ","nocombat","target") 
		end
	end
	--raid检查
	if flag then return flag end
	local partyx,partypetx
	for i=1,GetNumRaidMembers() do
		partyx = "raid"..i
		if(UnitExists(partyx))then
			if(UnitIsDead(partyx) )then
				flag = flag or JMacroConditionHandler(macroname,conf["dead"],targetType,true,prefnoharm.."\n/cast ","nocombat,target="..partyx,partyx) 
			else
				flag = flag or JMacroConditionHandler(macroname,conf["help"],targetType,true,prefnoharm.."\n/cast ","nocombat,target="..partyx,partyx) 
			end
		end
		--[[
		partypetx = "raidpet"..i
		if(UnitExists(partypetx))then
			if(not UnitIsDead(partypetx) )then
				flag = flag or JMacroConditionHandler(macroname,conf["help"],targetType,true,prefnoharm.."\n/cast ","nocombat,target="..partypetx,partypetx) 
			end
		end
		]]--
	end
	--小队成员检查
	if flag then return flag end
	local partyx,partypetx
	if(GetNumRaidMembers()<1)then
	for i=1,GetNumPartyMembers() do
		partyx = "party"..i
		if(UnitExists(partyx))then
			if(UnitIsDead(partyx) )then
				flag = flag or JMacroConditionHandler(macroname,conf["dead"],targetType,true,prefnoharm.."\n/cast ","nocombat,target="..partyx,partyx) 
			else
				flag = flag or JMacroConditionHandler(macroname,conf["help"],targetType,true,prefnoharm.."\n/cast ","nocombat,target="..partyx,partyx) 
			end
		end
		partypetx = "partypet"..i
		if(UnitExists(partypetx))then
			if(not UnitIsDead(partypetx) )then
				flag = flag or JMacroConditionHandler(macroname,conf["help"],targetType,true,prefnoharm.."\n/cast ","nocombat,target="..partypetx,partypetx) 
			end
		end
	end
	end
	--little pet
	
	--mount
	
	--JMacroPrint('find trac')
	if(flag)then return flag end
	local name, texture, active, category 
	local tracspells={}
	local tracspells1 = {}
	local flag=0
	--local pvpType = GetZonePVPInfo()
	for i = 1 , GetNumTrackingTypes() do
		name, texture, active, category = GetTrackingInfo(i)
		--JMacroPrint(name..category)
		if(category=='spell' --[[or pvpType=="friendly"]]--
			)then
			if(flag==0)then
				tracspells1[#tracspells1+1] = name
				if(active)then flag=1 end
			else
				tracspells[#tracspells+1] = name
			end
		end
	end
	for i=1, #tracspells1 do
		tracspells[#tracspells+1] = tracspells1[i]
	end
	if(#tracspells==0)then
		return JMacroEdit(macroname,prefno)
	end
	local text = prefix.."\n/castsequence "
	for i = 1, #tracspells do
		if(i==1)then
			text = text..tracspells[1]
		else
			text = text..","..tracspells[i]
		end
	end
	return JMacroEdit(macroname,text)
	
end


function JMacroTracHandler(macroname)
	local name, texture, active, category 
	local tracspells = {}
	local text = '#showtooltip\n/castsequence '
	local c=0
	for i = 1 , GetNumTrackingTypes() do
		name, texture, active, category = GetTrackingInfo(i)
		if(category=='spell')then
			c=c+1
			if(c==1)then 
				text = text ..name				
			else
				text = text ..','..name
			end
		end
	end
	local prefix = '#showtooltip\n/castsequence '
	return JMacroEdit(macroname,text)
end

function JMacroPartyHandler(macroname)
	--JMacroPartyMembers
	for k,v in pairs(JMacroPartyMacros) do
		local text = v[1]
		--是否队长
		if IsPartyLeader() then
			if v[2]~=nil then 
				text=v[2]
			else
				text = gsub(text,'party1target','target')
				text = gsub(text,'party1','player')
			end
		end
		for i =1,#JMacroPartyMembers do
			local m = JMacroPartyMembers[i]
			text= gsub(text,'#m'..i..'#',m)
		end
		--是否宏多份
		if string.find(k,'#m#') then
			for i =1,#JMacroPartyMembers do
				local m = JMacroPartyMembers[i]
				local k2 = gsub(k,'#m#',''..i)
				local text2 = gsub(text,'#m#',m)
				JMacroEdit(k2,text2)
			end
		else
			JMacroEdit(k,text)
		end
		
	end
end